/*
*  contact.c - Contact management functions
*  Copyright (c) 2005 Derek Ingrouville (dergro@users.sourceforge.net)
*
*  This program is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU Library General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#include <glib.h>
#include <stdlib.h>
#include <string.h>

#include "contact.h"
#include "utility.h"

MsnContact *
msn_contact_new ()
{
	MsnContact *contact = NULL;

	contact = g_new (MsnContact, 1);

	contact->passport = NULL;
	contact->nickname = NULL;
	contact->status = OFFLINE;
	contact->home_phone = NULL;
	contact->work_phone = NULL;
	contact->mobile_phone = NULL;
	contact->guid = NULL;
	contact->obj = NULL;
	contact->groups = NULL;
	contact->mobile = FALSE;
	contact->lists = 0;
	contact->type = 0;
	contact->ref_count = 0;

	g_print ("New contact\n");

	return contact;
}

MsnContact *
msn_contact_from_lst (MsnCommand *lst)
{
	/* LST N=email F=nickname [C=contact_guid] lists type [comma sep grps list] */
	
	/* Note: the contact_guid, F=nickname, and group list fields are optional
	 * C= and the grps will not appear if the contact is not on the forward list
	 * the F=nickname field may or may not appear if the contact is not on the FL
	 * a contact does not need to belong to a group so there may be no grp list */
	
	MsnContact *contact = NULL;
	char *url_decoded = NULL;
	int i = 0;

	g_return_val_if_fail (lst != NULL, NULL);
	g_return_val_if_fail (lst->param_count >= 2, NULL);

	g_printf ("Handling LST:\n%s\n", lst->command);
	/* Check if we have a valid LST */
	if (strcmp (lst->name, "LST") != 0)
		return NULL;

	contact = msn_contact_new ();
	
	for (i = 0; i < lst->param_count; i++) {
		g_printf ("processing param[%d] = %s\n", i, lst->params[i]);
		if (lst->params[i][0] == 'N' && lst->params[i][1] == '=')      /* N= */
			contact->passport = url_decode (lst->params[i] + 2);
		else if (lst->params[i][0] == 'F' && lst->params[i][1] == '=') /* F= */
			contact->nickname = url_decode ( lst->params[i] + 2);
		else if (lst->params[i][0] == 'C' && lst->params[i][1] == '=') /* N= */
			contact->guid = url_decode (lst->params[i] + 2);
		else {
			/* lists and type comes before any of the guids */
			contact->lists = atoi (lst->params[i++]);
			break;
		}
	}
	g_printf ("email = %s\n", contact->passport);
	contact->has_you = (contact->lists & 8) ? TRUE : FALSE;

	/* Check if contact is on the FL */
	if (!(contact->lists & 1)) {
		/* Contact is not on our FL 
		 * We don't care about them */
		return contact;
	}

	g_assert (i <= (lst->param_count));
	
	if (lst->params[i] != NULL && lst->param_count != i)
		msn_contact_set_groups (contact, lst->params[i]);
	else {
		contact->groups == NULL;
	}

	return contact;
}

/* boolean: check if contact is a member of the forward list */
inline int msn_contact_on_forwardlist (MsnContact *contact)
{
	return (contact->lists & 1);
}

void
msn_contact_free (MsnContact *contact)
{
	g_return_if_fail (contact != NULL);

	if (contact->ref_count > 0) {
		msn_contact_unref (contact);
		return;
	}

	g_print ("Free contact\n");

	if (contact->passport != NULL)
		g_free (contact->passport);

	if (contact->nickname != NULL)
		g_free (contact->nickname);

	if (contact->home_phone != NULL)
		g_free (contact->home_phone);

	if (contact->work_phone != NULL)
		g_free (contact->work_phone);

	if (contact->mobile_phone != NULL)
		g_free (contact->mobile_phone);
	
	if (contact->guid != NULL)
		g_free (contact->guid);

	if (contact->obj != NULL)
		msn_object_free (contact->obj);

	if (contact->groups != NULL)
		g_list_free (contact->groups);

	g_free (contact);

	return;
}

void
msn_contact_set_passport (MsnContact *contact, const char *passport)
{
	g_return_if_fail (contact != NULL);
	g_return_if_fail (passport != NULL);

	if (contact->passport != NULL)
		g_free (contact->passport);

	contact->passport = g_strdup (passport);
}

void
msn_contact_set_nickname (MsnContact *contact, const char *nickname)
{
	g_return_if_fail (contact != NULL);
	g_return_if_fail (nickname != NULL);

	if (contact->nickname != NULL)
		g_free (contact->nickname);

	contact->nickname = g_strdup (nickname);
}

int
msn_contact_set_groups (MsnContact *contact, const char *groups)
{
	char **split = NULL;
	int i;

	g_return_val_if_fail (contact != NULL, -1);
	g_assert (groups != NULL);

	split = g_strsplit (groups, ",", 0);

	for (i = 0; split[i]; i++) {
		char *guid = g_strdup (split[i]);
		contact->groups = g_list_append (contact->groups, guid);
	}

	return 0;
}

void
msn_contact_set_home_phone (MsnContact *contact, const char *home_num)
{
	g_return_if_fail (contact != NULL);
	g_return_if_fail (home_num != NULL);

	if (contact->home_phone != NULL)
		g_free (contact->home_phone);

	contact->home_phone = g_strdup (home_num);
}

void
msn_contact_set_work_phone (MsnContact *contact, const char *work_num)
{
	g_return_if_fail (contact != NULL);
	g_return_if_fail (work_num != NULL);

	if (contact->work_phone != NULL)
		g_free (contact->work_phone);

	contact->work_phone = g_strdup (work_num);
}

void
msn_contact_set_mobile_phone (MsnContact *contact, const char *mobile_num)
{
	g_return_if_fail (contact != NULL);
	g_return_if_fail (mobile_num != NULL);

	if (contact->mobile_phone != NULL)
		g_free (contact->mobile_phone);

	contact->mobile_phone = g_strdup (mobile_num);
}

void
msn_contact_set_msn_object (MsnContact *contact, MsnObject *obj)
{
	g_return_if_fail (contact != NULL);
	g_return_if_fail (obj != NULL);

	if (contact->obj != NULL)
		msn_object_free (contact->obj);

	contact->obj = obj;
}
